import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { DataScopeEnum, DelFlagEnum } from 'src/common/enum'
import { Repository, SelectQueryBuilder } from 'typeorm'
import { SysDeptEntity } from './entities/dept.entity'

@Injectable()
export class DeptService {
  constructor(
    @InjectRepository(SysDeptEntity)
    private readonly sysDeptEntityRep: Repository<SysDeptEntity>
  ) {}
  /**
   * 根据数据权限范围和部门ID查询部门ID列表。
   * @param deptId 部门ID，表示需要查询的部门。
   * @param dataScope 数据权限范围，决定查询的部门范围。
   * @returns 返回一个部门ID数组，根据数据权限范围决定返回的部门ID集合。
   */
  async findDeptIdsByDataScope(deptId: number, dataScope: DataScopeEnum) {
    try {
      const entity = this.sysDeptEntityRep.createQueryBuilder('dept')
      // 筛选出删除标志为未删除的部门
      entity.where('dept.delFlag = :delFlag', { delFlag: DelFlagEnum.NORMAL })
      if (dataScope === DataScopeEnum.DATA_SCOPE_DEPT) {
        // 本部门的数据权限，则只查询指定部门
        this.addQueryForDeptDataScope(entity, deptId)
      } else if (dataScope === DataScopeEnum.DATA_SCOPE_DEPT_AND_CHILD) {
        // 本部门以及子部门的数据权限，则查询指定部门及其所有子部门
        this.addQueryForDeptAndChildDataScope(entity, deptId)
      } else if (dataScope === DataScopeEnum.DATA_SCOPE_SELF) {
        // 仅本人数据权限，不查询任何部门，返回空数组
        return []
      }
      // 执行查询并获取结果
      const list = await entity.getMany()
      // 查询结果映射为部门 ID 数组后返回
      return list.map((item) => item.deptId)
    } catch (error) {
      console.error('Failed to query department IDs:', error)
      throw new Error('Querying department IDs failed')
    }
  }
  /**
   * 添加查询条件以适应本部门数据权限范围。
   * @param queryBuilder 查询构建器实例
   * @param deptId 部门ID
   */
  private addQueryForDeptDataScope(
    queryBuilder: SelectQueryBuilder<SysDeptEntity>,
    deptId: number
  ) {
    queryBuilder.andWhere('dept.deptId = :deptId', { deptId: deptId })
  }
  /**
   * 添加查询条件以适应本部门及子部门数据权限范围。
   * @param queryBuilder 查询构建器实例
   * @param deptId 部门ID
   */
  private addQueryForDeptAndChildDataScope(
    queryBuilder: SelectQueryBuilder<SysDeptEntity>,
    deptId: number
  ) {
    queryBuilder
      .andWhere('dept.ancestors LIKE :ancestors', {
        ancestors: `%${deptId}%`
      })
      .orWhere('dept.deptId = :deptId', { deptId: deptId })
  }
}
